// �����˸��-------�������ս
#include <iostream>
#include <easyx.h>
#include <time.h>
#include <math.h>
#define Wide 1280
#define Hight 640
#define Wide_map (Wide * 5)
#define Hight_map (Hight * 5)
#define Food_num 3000
#define Enemy_num 288
#define Invincibility 50
// ������Ϸ��ͼ
IMAGE map(Wide_map, Hight_map);
// ����ʱ���޵�ʱ��
int invincibility = Invincibility;
// ����ٶ�
int player_sleep = 4;
int l = 3;
int enemy_sleep = 3;
struct Ball
{
    int x;
    int y;
    float r;
    DWORD color;
};
struct Ball player;
struct Ball Food[Food_num];
struct Ball Enemy[Enemy_num];
/*
�����С��ĳ�ʼλ�������ڴ��ڵ��м䣬�뾶��СΪ15��
ʳ��С���aiС���λ����ͨ��rand������srand������time�������ɵ������������ֲ��ڵ�ͼ�ĸ���λ�ã�
ʳ��С��뾶Ϊ1-5��aiС��İ뾶15-30���.����������ʹ����RGB�������һ����ɫ��ʹÿ��ʳ��С�����ɫ�������
*/

// ��ʼ���������
void Inset()
{
    srand((unsigned)time(NULL)); // ����
    // srand(time(0));
    player.x = Wide / 2;
    player.y = Hight / 2;
    player.r = 25;
    for (int i = 0; i < Food_num; i++)
    {
        Food[i].x = rand() % Wide_map;
        Food[i].y = rand() % Hight_map;
        Food[i].r = rand() % 5 + 1;
        Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
    for (int i = 0; i < Enemy_num; i++)
    {
        Enemy[i].x = rand() % Wide_map;
        Enemy[i].y = rand() % Hight_map;
        Enemy[i].r = rand() % 15 + 15;
        Enemy[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
    }
}
/*
�õ�GetAsyncKeyState()������ȡ�첽����״̬()�����ǰ���
*/
// ��Ҳ���
void Player_move()
{
    if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState(0x57))
    {
        if (player.y > 0)
        {
            player.y -= player_sleep;
        }
    }
    if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState(0x53))
    {
        if (player.y < Hight_map)
            player.y += player_sleep;
    }
    if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState(0x41))
    {
        if (player.x > 0)
            player.x -= player_sleep;
    }
    if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState(0x44))
    {
        if (player.x < Wide_map)
            player.x += player_sleep;
    }
    if (GetAsyncKeyState(0x20) || GetAsyncKeyState(VK_SHIFT))
    {
        player_sleep = l + 3;
    }
    /*if (GetAsyncKeyState(VK_ESCAPE)) //ֱ�ӽ���
    {
        closegraph();
    }*/
    else
    {
        player_sleep = l;
    }
}
/*
�������0-399�����ֻ��������ʾaiС���������ҵ��ƶ���������0-3��ԭ�����������̫С������С��ͻ������ƶ��ˡ�
�����С����aiС�򿿽�ʱ��aiС���׷���������ܣ�����������Ҫ�ȼ���С���֮���ŷ����þ��루������빫ʽ��
Ȼ���ж���С��ľ����Ƿ�С��50�����ص㣬���ж��Ƿ�С�����С��İ뾶 + aiС��İ뾶 + 50��
�ж����Ƚ���С��İ뾶��С�����aiС��İ뾶�������С��İ뾶����ôaiС���Ҫ׷�����С��
��aiС���������Ҫ�������С������꣬�������aiС���x�������С���x��ôaiС���x�ͼ�С��ͬ��y��С����֮��
ͬ��С�����ܡ�
*/

// ����
int Distance(int x, int y, int x1, int y1)
{
    return sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
}
// �����ƶ�
void Enemy_move()
{
    srand((unsigned)time(NULL));
    for (int i = 0; i < Enemy_num; i++)
    {
        int direction = rand() % 400;

        if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) > player.r + Enemy[i].r + 50)
        {
            if (direction < 100) // ����
            {
                if (Enemy[i].y > 0)
                    Enemy[i].y -= enemy_sleep;
            }
            if (direction < 200 && direction >= 100) // ����
            {
                if (Enemy[i].y < Hight_map)
                    Enemy[i].y += enemy_sleep;
            }
            if (direction < 300 && direction >= 200) // ����
            {
                if (Enemy[i].x > 0)
                    Enemy[i].x -= enemy_sleep;
            }
            if (direction < 400 && direction >= 300) // ����
            {
                if (Enemy[i].x < Wide_map)
                    Enemy[i].x += enemy_sleep;
            }
        }
        // ����׷�����
        if (Distance(player.x, player.y, Enemy[i].x, Enemy[i].y) <= player.r + Enemy[i].r + 50)
        {
            if (Enemy[i].r > player.r)
            {
                if (Enemy[i].x < player.x)
                {
                    if (Enemy[i].x < Wide_map)
                        Enemy[i].x += enemy_sleep;
                }
                if (Enemy[i].x > player.x)
                {
                    if (Enemy[i].x > 0)
                        Enemy[i].x -= enemy_sleep;
                }
                if (Enemy[i].y < player.y)
                {
                    if (Enemy[i].y < Hight_map)
                        Enemy[i].y += enemy_sleep;
                }
                if (Enemy[i].y > player.y)
                {
                    if (Enemy[i].y > 0)
                        Enemy[i].y -= enemy_sleep;
                }
            }
            // ��������
            else
            {
                if (Enemy[i].x < player.x)
                {
                    if (Enemy[i].x > 0)
                    {
                        Enemy[i].x -= enemy_sleep;
                    }
                }
                if (Enemy[i].x > player.x)
                {
                    if (Enemy[i].x < Wide_map)
                    {
                        Enemy[i].x += enemy_sleep;
                    }
                }
                if (Enemy[i].y < player.y)
                {
                    if (Enemy[i].y > 0)
                    {
                        Enemy[i].y -= enemy_sleep;
                    }
                }
                if (Enemy[i].y > player.y)
                {
                    if (Enemy[i].y < Hight_map)
                    {
                        Enemy[i].y += enemy_sleep;
                    }
                }
            }
        }
    }
}
/*
С��֮�������ɹ�ϵ��
����С���Բ��С�������Ǹ�Բ�İ뾶ʱ��С���Ǹ���ͻᱻ�Ե���
���Ե���С������λ�����ɣ��������⣩������󣬳Ե��Ǹ�С��뾶���ӱ���С��뾶����ʮ��֮һ��
*/
// ��ʳ��
void EatFood()
{
    for (int i = 0; i < Food_num; i++)
    {
        // ��ҳ�ʳ��
        if (Distance(player.x, player.y, Food[i].x, Food[i].y) < player.r)
        {
            player.r += Food[i].r / 50;
            Food[i].x = rand() % Wide_map;
            Food[i].y = rand() % Hight_map;
            Food[i].r = rand() % 5 + 1;
            Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
        }
    }
    for (int j = 0; j < Enemy_num; j++)
    {
        // ���˳�ʳ��
        for (int i = 0; i < Food_num; i++)
        {
            if (Distance(Enemy[j].x, Enemy[j].y, Food[i].x, Food[i].y) < Enemy[j].r)
            {
                Enemy[j].r += Food[i].r / 50;
                Food[i].x = rand() % Wide_map;
                Food[i].y = rand() % Hight_map;
                Food[i].r = rand() % 5 + 1;
                Food[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            }
        }
        // ���˳Ե���
        for (int i = 0; i < Enemy_num; i++)
        {
            if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[j].r && Enemy[j].r > Enemy[i].r)
            { // j��i
                Enemy[j].r += Enemy[i].r / 50;
                Enemy[i].x = rand() % Wide_map;
                Enemy[i].y = rand() % Hight_map;
                Enemy[i].r = rand() % 10 + 15;
                Enemy[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            }
            if (Distance(Enemy[j].x, Enemy[j].y, Enemy[i].x, Enemy[i].y) < Enemy[i].r && Enemy[j].r < Enemy[i].r)
            { // i��j
                Enemy[i].r += Enemy[j].r / 50;
                Enemy[j].x = rand() % Wide_map;
                Enemy[j].y = rand() % Hight_map;
                Enemy[j].r = rand() % 10 + 15;
                Enemy[j].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            }
        }
        if (Distance(player.x, player.y, Enemy[j].x, Enemy[j].y) < player.r)
        {
            // ��ҳԵ���
            if (player.r > Enemy[j].r)
            {
                player.r += Enemy[j].r / 10;
                Enemy[j].x = rand() % Wide_map;
                Enemy[j].y = rand() % Hight_map;
                Enemy[j].r = rand() % 10 + 15;
                Enemy[j].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            }
            // ���˳����
            else
            { /*����Ϊʲô�����������--�����޵�ʱ�䣺Ҫ��һ��ʱ��ȱ�������0�������ѭ���ǻ�һֱִ�еģ�����
              һ�����ֵз��ܳԵ��ҷ���ʱ�������Ǳ���Ϊ0��ʱ��Ҳ�ͻ��Ϊ�޵�ʱ�䡣
              */
                if (invincibility == 0)
                {
                    Enemy[j].r += player.r / 10;
                    player.x = Wide / 2;
                    player.y = Hight / 2;
                    player.r = 15;
                    invincibility = Invincibility;
                }
            }
        }
    }
}
/*
С����һ��ʵ��Բ����easyxͼ�ο����ṩ��һ����ʵ��Բ�ĺ�����solidcircle����������ʾ����С��Ĭ����ɫΪ��ɫ��
Ϊ�˷������ֲ�ͬ��С�����ǻ���ʹ��setfillcolor�������ı�С�����ɫ
��Ϊ��ʾ�ĺ�������Ҳ���С��ĺ����ȶ��Ƿ���ͬһ��whileѭ���ظ�ִ�еģ������ͻ��ظ���ʾС��
���Ի���Ҫ�õ�һ����������cleardevice�����վ���ÿִ��һ�ξ�����ͶӰһ��
ʹ��setbkcolor(rgb)�����޸Ĵ��ڵı�����ɫ��

*/
// ��ʾ
void Show()
{
    // ���õ�ͼ
    SetWorkingImage(&map);
    // ����
    cleardevice();
    // ������ɫ
    setbkcolor(RGB(46, 47, 68));
    // ʳ��
    for (int i = 0; i < Food_num; i++)
    {
        setfillcolor(Food[i].color);
        solidcircle(Food[i].x, Food[i].y, Food[i].r);
    }
    // ����
    for (int i = 0; i < Enemy_num; i++)
    {
        setfillcolor(Enemy[i].color);
        solidcircle(Enemy[i].x, Enemy[i].y, Enemy[i].r);
    }
    // ���
    setfillcolor(RED);
    solidcircle(player.x, player.y, player.r);
    SetWorkingImage();

    int x = player.x - (Wide / 2);
    int y = player.y - (Hight / 2);
    // ��ֹ����Խ��
    if (x < 0)
        x = 0;
    if (y < 0)
        y = 0;
    if (x > Wide_map - Wide)
        x = Wide_map - Wide;
    if (y > Hight_map - Hight)
        y = Hight_map - Hight;
    // ��map�����������
    putimage(0, 0, Wide, Hight, &map, x, y);
}
int main()
{
    initgraph(Wide, Hight); // ��ʼ����ͼ����
    Inset();                // Ԥ����
    // ����
    /*
    ����������ڿ�ʼ������ͼ��
    ִ�к��κλ�ͼ����������ʱ���������ͼ�����ϣ�
    ֱ��ִ�� FlushBatchDraw �� EndBatchDraw �Ž�֮ǰ�Ļ�ͼ�����
    */
    BeginBatchDraw();
    while (1)
    {
        if (invincibility > 0)
            invincibility--;
        Show();
        // ��Ҳ���
        Player_move();
        Enemy_move();
        EatFood();
        if (GetAsyncKeyState(VK_ESCAPE)) // ֱ�ӽ���
        {
            closegraph();
        }
        // ˢ��
        FlushBatchDraw();
    }
    closegraph();
    return 0;
}